package com.skyable.account.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.skyable.account.entity.SysCompany;
import com.skyable.account.entity.SysCompanyApply;
import com.skyable.account.entity.SysDept;
import com.skyable.account.entity.SysUser;
import com.skyable.account.feign.ThirdFeignApi;
import com.skyable.account.mapper.CompanyApplyMapper;
import com.skyable.account.service.ICompanyApplyService;
import com.skyable.account.service.ICompanyService;
import com.skyable.account.service.IDeptService;
import com.skyable.account.service.IUserService;
import com.skyable.common.annotation.SaFeignClient;
import com.skyable.common.api.cloud.SaService;
import com.skyable.common.common.ResponseResult;
import com.skyable.common.common.ServiceResult;
import com.skyable.common.constants.exception.AccountExcpConstants;
import com.skyable.common.constants.param.CommonParams;
import com.skyable.common.utils.ChineseCharacterUtil;
import com.skyable.common.utils.PasswordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author GaoYuan
 * @title: CompanyApplyServiceImpl
 * @projectName private-cloud
 * @description: TODO
 * @date 2021/6/3013:53
 */
@Service
public class CompanyApplyServiceImpl extends ServiceImpl<CompanyApplyMapper,SysCompanyApply> implements ICompanyApplyService {

    @Autowired
    private SaService saService;
    @Autowired
    private ThirdFeignApi thirdFeignApi;
    @Autowired
    private ICompanyService companyService;
    @Autowired
    private IDeptService deptService;
    @Autowired
    private IUserService userService;

    private static PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Override
    public ServiceResult<SysCompanyApply> sysCompanyApply(SysCompanyApply sysCompanyApply) {
        ServiceResult<SysCompanyApply> serviceResult = new ServiceResult<>();
        SysCompanyApply companyApply = lambdaQuery().eq(SysCompanyApply::getPhone, sysCompanyApply.getPhone()).one();
        if(companyApply != null) {
            serviceResult.setError(AccountExcpConstants.ERROR_CODE_USER_PHONE_EXISTS, AccountExcpConstants.ERROR_MSG_USER_PHONE_EXISTS);
            return serviceResult;
        }
        sysCompanyApply.setApplyTime(new Date());
        sysCompanyApply.setApplyStatus(0);
        baseMapper.insert(sysCompanyApply);
        serviceResult.setResult(sysCompanyApply);
        return serviceResult;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceResult<SysCompanyApply> adviceCompanyApply(Long id, Integer applyStatus, String applyAdvice) {
        ServiceResult<SysCompanyApply> serviceResult = new ServiceResult<>();
        SysCompanyApply companyApply = lambdaQuery().eq(SysCompanyApply::getId, id).one();
        companyApply.setApplyStatus(applyStatus);
        companyApply.setApplyAdvice(applyAdvice);
        companyApply.setCheckTime(new Date());
        //根据请求结果发送短信
        if(applyStatus == 1) {
            //审核通过 创建用户并发送用户密码
            //1.创建用户
            HashMap<String, Object> paramMap = new HashMap<>();
            paramMap.put("majorDomainName", companyApply.getCompanyName());
            paramMap.put("majorDomainDesc", companyApply.getCompanyDesc());
            String majorDomainResult = saService.createMajorDomain(paramMap);
            JSONObject resultObj = JSONObject.parseObject(majorDomainResult);
            if(resultObj.containsKey(CommonParams.ERROR_CODE)) {
                serviceResult.setError(resultObj.getInteger(CommonParams.ERROR_CODE), resultObj.getString(CommonParams.ERROR_DESC));
                return serviceResult;
            }
            Long domainId = resultObj.getLong(CommonParams.MAJOR_DOMAIN_ID);

            //3.创建公司（租户）
            SysCompany sysCompany = new SysCompany();
            sysCompany.setCompanyDesc(companyApply.getCompanyDesc());
            sysCompany.setCompanyName(companyApply.getCompanyName());
            sysCompany.setDomainId(domainId);
            sysCompany.setEmail(companyApply.getEmail());
            sysCompany.setPhone(companyApply.getPhone());
            sysCompany.setName(companyApply.getUserName());
            companyService.insertCompany(sysCompany);

            //4.创建租户顶级部门为公司名称
            SysDept sysDept = new SysDept();
            sysDept.setStatus(0);
            sysDept.setDelFlag(0);
            sysDept.setAncestors("");
            sysDept.setDeptCode(ChineseCharacterUtil.getUpperCase(sysCompany.getCompanyName(), true));
            sysDept.setDeptName(sysCompany.getCompanyName());
            sysDept.setLeader(sysCompany.getName());
            sysDept.setPhone(sysCompany.getPhone());
            sysDept.setEmail(sysCompany.getEmail());
            sysDept.setCompanyId(sysCompany.getId());
            deptService.insertDept(sysDept);

            //5.创建租户管理员
            SysUser sysUser = new SysUser();
            //2表示租户管理员账号
            sysUser.setUserType(2);
            sysUser.setDomainId(domainId);
            sysUser.setDeptId(sysDept.getId());
            sysUser.setUsername(sysCompany.getName());
            //获取初始化密码
            String password = PasswordUtil.randomPassword();
            sysUser.setPassword(passwordEncoder.encode(password));
            sysUser.setPhone(sysCompany.getPhone());
            sysUser.setEmail(sysCompany.getEmail());
            sysUser.setStatus(0);
            sysUser.setDelFlag(0);
            userService.insertUser(sysUser, null);

            //6.发送用户密码
            Map<String,String> param = new HashMap<>(2);
            param.put(CommonParams.SMS_PHONE, sysUser.getPhone());
            param.put(CommonParams.SMS_PASS, password);
            ResponseResult sendResult = thirdFeignApi.sendPass(param);
            int count = 3;
            //发送失败重试三次
            while(!sendResult.isSuccess() && count > 0) {
                count--;
                sendResult = thirdFeignApi.sendPass(param);
            }

            //7.更新申请信息
            baseMapper.updateById(companyApply);

            //8.TODO 创建device表和account表
            userService.createCompanyTable(domainId);

        } else if(applyStatus == 2) {
            //审核不通过
            Map<String,String> param = new HashMap<>();
            param.put(CommonParams.SMS_PHONE, companyApply.getPhone());
            param.put(CommonParams.SMS_REASON, applyAdvice);
            thirdFeignApi.sendDeny(param);

            //更新申请信息
            baseMapper.updateById(companyApply);
        }
        serviceResult.setResult(companyApply);
        return serviceResult;
    }

    @Override
    public ServiceResult<Page<SysCompanyApply>> sysCompanyApplyList(SysCompanyApply sysCompanyApply, Integer page, Integer limit) {
        ServiceResult<Page<SysCompanyApply>> serviceResult = new ServiceResult<>();
        Page<SysCompanyApply> sysCompanyApplyPage = new Page<>(page, limit);
        QueryWrapper<SysCompanyApply> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(sysCompanyApply);
        queryWrapper.orderByDesc(CommonParams.ORDER_APPLY_TIME);
        Page<SysCompanyApply> result = baseMapper.selectPage(sysCompanyApplyPage, queryWrapper);
        serviceResult.setResult(result);
        return serviceResult;
    }
}
